package com.humdeef.socket;



import javax.print.DocFlavor;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * nio类型的socket
 */
public class NioSocketDemo {
    private static Selector selector;

    public static void main(String[] args) throws IOException {
        initServer(8888);
        listenServer();
    }


    private static void initServer(int port) throws IOException {
        //初始化
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //设置为非阻塞型io
        serverSocketChannel.configureBlocking(false);
        //绑定端口
        serverSocketChannel.socket().bind(new InetSocketAddress(port));

        //初始化selector
        selector = Selector.open();
        //注册selector到管道上面
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("服务已经启动。。。。");
    }

    private static void listenServer() throws IOException {
        //轮训监听selector
        while (true) {
            //等待客户连接
            //select 模式，多路复用
            selector.select();   //这里会等待客户端的连接会阻塞

            Iterator<SelectionKey> selectionKey = selector.selectedKeys().iterator();
            //轮训客户端的连接
            while (selectionKey.hasNext()) {
                SelectionKey next = selectionKey.next();
                //移除掉事件
                selectionKey.remove();
                handlerEvent(next);
            }

        }
    }

    private static void handlerEvent(SelectionKey key) throws IOException {
        if (key.isAcceptable()) {
            //处理客户端连接事件
            ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
            SocketChannel socketChannel = serverSocketChannel.accept();
            socketChannel.configureBlocking(false);
            //接收客户端发送的信息时，需要设置read的权限
            socketChannel.register(selector, SelectionKey.OP_READ);
        } else if (key.isReadable()) {
            //处理读取客户端发送信息的事件
            SocketChannel socketChannel = (SocketChannel) key.channel();
            ByteBuffer byteBuffer =ByteBuffer.allocate(1024);
            int read = socketChannel.read(byteBuffer);
            //读到了数据
            if(read>0){
                String result = new String(byteBuffer.array(), "UTF-8").trim().toString();
                System.out.println("服务端收到的结果为："+result);
            }else {
                 //没有读取到数据
                System.out.println("客户端关闭了。。。");
                key.cancel();
            }

        }
    }
}
